#ifndef __qyscript__
#define __qyscript__

#include <QObject>
#include <QScriptValue>
#include <QScriptEngine>
#include <QStringList>

//! Макрос регистрации типов, наследованных от QObject. После регистрации, становится возможным создавать объекты заданного типа прямо в скрипте, используя оператор new.
#define QY_SCRIPT_REGISTER_QOBJECTBASETYPE( script, type ) { QScriptValue prototype = script.engine()->scriptValueFromQMetaObject<type>();script.engine()->globalObject().setProperty( #type, prototype ); }

/*! \class QyScript
	\brief Класс QyScript служит для выполнения скриптов из файлов, а также несколько расширяет возможности интерпритатора.

	QyScript самостоятельно обрабатывает ошибки найденные в коде скрипта, при этом он останавливает выполнение скрипта и эмитирует соответствующий сикнал scriptError.
	На этапе выполнения в контексте интерпритатора регистрируется объект script (QyScript регистрирует сам себя в интерпритаторе), который позволяет пользователю использовать расширения.

	Расширения:
	* include
	* addResource
	* importExtension
	* availableExtensions
	* importedExtensions
	* loadUiFile
	* readAllFromFile

	Так же, на этапе выполнения, доступно свойство systemEnvironment, в которую помещаются все переменные окружения. Доступ к значениям осуществляется по ключу, ключем является название переменной окружения.

*/
class QyScript : public QObject {
	Q_OBJECT
public:
	QyScript( QObject * parent=0 );
	~QyScript();

	QScriptEngine * engine() const { return p_engine; } //!< получить указатель на интерпритатор
	bool evaluateFile( const QString & fileName ); //!< выполнить файл
	bool addGlobalObject( QObject * object, QString name=QString() ); //!< сделать object доступным из скрипта
	QStringList lastEvaluatedFiles() const { return evaluatedFiles; } //!< возвращает список выполненных файлов, во время последнего вызова evaluateFile
	Q_INVOKABLE bool include( const QString & fileName ); //!< вставка
	Q_INVOKABLE bool addResource( const QString & fileName ); //!< зарегестрировать файл ресурсов
	Q_INVOKABLE bool importExtension( const QString & name ); //!< задействовать расширение
	Q_INVOKABLE QStringList availableExtensions() const; //!< список доступных расширений
	Q_INVOKABLE QStringList importedExtensions() const; //!< список задействованных расширений
	Q_INVOKABLE QWidget * loadUiFile( const QString & fileName, QWidget * parent ); //!< загрузить ui - файл
	Q_INVOKABLE QString readAllFromFile( const QString & fileName ) const; //!< считать файл целиком

	static void generatePropertyMap( const QScriptValue & object, const QString & name,
		QMap<QString,QVariant> & propertyMap ); //!< генерирует список свойств: имя - значение, на основе данных взятых из QScriptValue

signals:
	void scriptError( const QString & text, const QString & fileName, int line,
		QStringList backtrace ); //!< сигнал об ошибке в коде скрипта

private:
	bool internalEvaluateFile( const QString & fileName );
	bool checkErrors();

	QScriptEngine * p_engine; // интерпритатор
	QStringList evaluatedFiles; // уже выполненные файлы

};

#endif/*__qyscript__*/
